Skip to content

docs(teams): accurate setup wizard + env + Graph permissions#212

Merged
alan5543 merged 5 commits into
mainfrom
fix/teams-setup-wizard-accuracy
Jun 1, 2026
Merged

docs(teams): accurate setup wizard + env + Graph permissions#212
alan5543 merged 5 commits into
mainfrom
fix/teams-setup-wizard-accuracy

Conversation

@alan5543
Copy link
Copy Markdown
Member

@alan5543 alan5543 commented Jun 1, 2026

Recreated from #210, which GitHub auto-closed when its base branch (feat/teams-graph-ingestion) was deleted after #206 merged. Branch has been rebased onto main; the diff is identical to the reviewed #210.

Why

The Connect Microsoft Teams wizard had multiple silent traps that took an internal user (Alan) a full real onboarding cycle and a stack of session memory to work through. Each had a specific failure mode:

Wizard gap Real-world failure
App Type placeholder = `MultiTenant` MSAL `missing_tenant_id_error`. Caller had to dig through the bot logs to understand.
No mention of `Channel.ReadBasic.All` admin consent TeamsBridge.listChannels (Graph enum, introduced in #206) returns `[]` silently. Sidebar workspace looks empty for no apparent reason.
No mention of "only Global Admin can consent" App Admin / Cloud App Admin → `Authorization_RequestDenied`. Several hours lost on a wrong consent path.
No messaging endpoint format Caller guessed `/api/messages` (Bot Framework default) and the bot ignored every activity.
No ngrok callout Caller had to discover from log lines that the bot expected a public HTTPS endpoint.
No Teams app .zip install step Bot registered correctly in Azure but never appeared in Teams.

What

  1. Rewrite `TEAMS_INSTRUCTIONS` in `ConnectionWizard.tsx` to 8 numbered steps with sub-bullets covering: SingleTenant choice (with rationale), client-secret VALUE vs ID, tenant id source, Microsoft Teams channel enable, `Channel.ReadBasic.All` admin consent (Global Admin), messaging endpoint format with ngrok callout, and the .zip app install.
  2. Extend `CredentialField` with optional `enum`, `default`, `hint`. `app_type` now renders as a `` (`SingleTenant` | `MultiTenant`) with `SingleTenant` as the auto-filled default; `app_tenant_id` carries a hint explaining the requirement. No regression for the four other platforms (none use the new fields). Replace the generic Teams branch of `StepWebhookMode` with a dedicated `TeamsWebhookMode` panel — three concrete post-validation cards (endpoint URL, Graph permission, Teams app package) with exact code blocks. `bot/README.md` env table now includes `TEAMS_APP_TENANT_ID` with the SingleTenant-vs-MultiTenant explainer. `docs/content/getting-started/teams-setup.mdx` — env var names fixed (the doc previously referenced `TEAMS_TENANT_ID` / `TEAMS_CLIENT_ID` / `TEAMS_CLIENT_SECRET`, which are not read by the bot), permissions table replaced with the actually-required `Channel.ReadBasic.All` (RSC permissions live in the manifest now). Added a callout pointing users to the wizard. Test plan [x] `npx tsc --noEmit` on `web/` clean [x] `npx eslint web/src/components/settings/ConnectionWizard.tsx` clean (0 errors) [x] Verifier agent independently checked: credential key round-trip (snake → camel) intact via `bot/src/index.ts` line 180 + `chat-manager.ts` lines 218–223; `useEffect` auto-fill safe (`fields` is a module-level constant, fires exactly once per mount); `` state persists across step navigation; no regression to slack/discord/telegram/mattermost `CREDENTIAL_FIELDS` entries.
  3. Visual smoke (post-merge, by reviewer): open Settings → Integrations → Connect Microsoft Teams in the running stack; confirm the new instructions, the SingleTenant default in the App Type dropdown, the hint text under Tenant ID, and the three-card `TeamsWebhookMode` panel on the Channels step.
  4. Behavior change

    • New optional fields on `CredentialField` — backward-compatible.
    • `app_type` is now a controlled `` for Teams; the wire format sent to the backend is unchanged (still a snake_case string). No backend or bot code paths touched. 🤖 Generated with Claude Code

alan5543 and others added 5 commits June 1, 2026 00:08
The Connect Microsoft Teams wizard's instructions, credential form,
and post-validation panel previously omitted everything that turns a
real-world Teams setup into a working Beever Atlas connection:

  • The App Type field placeholder was "MultiTenant", which produces
    an MSAL `missing_tenant_id_error` against any tenant-scoped Azure
    Bot. SingleTenant is the supported path, but nothing in the UI
    said so.
  • No mention of the Microsoft Graph `Channel.ReadBasic.All`
    application permission required for the Graph-based channel
    enumeration introduced in #206 — and no warning that ONLY a
    Global Administrator can consent it (Application Administrator
    and Cloud Application Administrator both return
    `Authorization_RequestDenied`).
  • No mention of the messaging endpoint format — users were left
    guessing whether it's `/api/messages`, `/api/teams`, or
    `/api/webhooks/teams`. The bot listens on `/api/teams` (see
    `bot/src/index.ts:422`).
  • No mention of ngrok for local dev, despite the bot needing a
    publicly reachable HTTPS endpoint to receive Bot Framework
    activities.
  • No mention of installing the Teams app package
    (`bot/teams-app/beever-atlas-teams.zip`) — without that step
    the bot never appears in the team.

This change:

  1. Rewrites `TEAMS_INSTRUCTIONS` (8 numbered steps with sub-bullets
     for non-obvious details, ngrok callout, admin-consent gotcha,
     and the .zip install path).
  2. Extends `CredentialField` with optional `enum`, `default`, and
     `hint` so `app_type` renders as a `<select>` (SingleTenant /
     MultiTenant) defaulting to SingleTenant and the
     `app_tenant_id` field carries a "why required" hint. No
     regression for the other four platforms — none of them use the
     new fields.
  3. Replaces the generic Teams branch of `StepWebhookMode` with a
     dedicated `TeamsWebhookMode` panel covering the three concrete
     post-validation steps (endpoint URL, Graph permission, Teams
     app package).
  4. Fixes `bot/README.md` env table to include
     `TEAMS_APP_TENANT_ID` and explain SingleTenant vs MultiTenant.
  5. Fixes `docs/content/getting-started/teams-setup.mdx` env var
     names (the doc previously referenced `TEAMS_TENANT_ID` /
     `TEAMS_CLIENT_ID` / `TEAMS_CLIENT_SECRET`, which are not read
     by the bot) and replaces the historical Graph permissions
     table with the actually-required `Channel.ReadBasic.All`
     (RSC permissions live in the manifest now).

Verified:
- `npx tsc --noEmit` clean
- `npx eslint` on `ConnectionWizard.tsx` clean
- Verifier agent confirmed: credential field key round-trip
  (snake → camel) intact, no regression for slack/discord/
  telegram/mattermost CREDENTIAL_FIELDS entries, `<select>` state
  persists across step navigation.

Stacked on top of #206 because the wizard text describes the Graph
channel enumeration introduced there (`TeamsBridge.listChannels`'s
call to `teams.channels.list`). Retarget to `main` once #206 lands.

Confidence: high
Scope-risk: narrow — UI text + one optional schema extension; no
  backend or bot code paths touched.
Directive: keep the `app_type` enum values in lockstep with the
  Chat SDK adapter's `createTeamsAdapter` accepted values. The
  adapter treats anything other than literal "MultiTenant" as
  SingleTenant — so a typo here doesn't fail loudly, it fails
  silently as a missing-tenant-id MSAL error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First pass turned every step into a paragraph with parenthetical
rationale and warning callouts; the result rendered as a vertical
wall of prose, monospace sub-bullets full of long sentences, and a
3-card post-validation panel that re-stated info from the setup
list. User feedback: "UX is bad."

This trim:

  • Reduces setup from 8 long steps to 6 single-line imperatives.
    Each step says WHAT to click; rationale ("required so MSAL
    client_credentials can mint the Graph token") is removed —
    users don't need that to follow the click path.
  • Reserves the `details` slot (monospace) for things that should
    actually be monospaced: an enum value, a permission name.
    Prose details made the layout feel like a code listing.
  • Moves the messaging endpoint, ngrok instructions, and Teams
    app `.zip` install OUT of setup and INTO the post-validation
    `TeamsWebhookMode` panel — they happen AFTER credentials
    validate, so putting them in the upfront list both bloated
    setup and skipped the natural workflow break.
  • Drops the redundant Channel.ReadBasic.All card from
    TeamsWebhookMode — it's already in setup step 6, and
    repeating it implied "do this again" rather than "review."
  • TeamsWebhookMode is now 2 cards instead of 3, with shorter
    body copy.

Verified:
- `npx tsc --noEmit` on `web/` clean
- Web image rebuilt and deployed; localhost:3000 returns HTTP 200
- The instruction list now scrolls minimally above the Display
  Name input

Confidence: high
Scope-risk: narrow — UI text only.
Directive: the `details` array on a setup-step instruction renders
  in monospace. Use it for code-shaped values (paths, enum values,
  command snippets), NEVER for prose explanations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…es supported

User-reported gaps after the first trim:
  • The setup steps explained creds/Azure but never told users
    HOW to get a public webhook URL (ngrok) or WHERE to enter the
    bot URL — they were left guessing whether we needed it as a
    wizard field. We don't (bot listens on a fixed path), but the
    setup list must say so.
  • The App Type hint read as "we only support SingleTenant" when
    in fact the select offers both and the SDK accepts either.

Changes:
  • Setup step 2 (new): "Expose this bridge over HTTPS, then set
    the Bot's Messaging endpoint to your URL + /api/teams" with
    mono details for `ngrok http 3001` and the URL pattern. This
    surfaces what was previously buried in the post-validation
    panel.
  • Setup step 1 detail updated to "SingleTenant (recommended) or
    MultiTenant" so the choice is visible upfront.
  • App Type hint rewritten to lead with "Both modes are
    supported" — no longer reads as a restriction.
  • TeamsWebhookMode collapses from 2 cards to 1: just the .zip
    app install. The endpoint card moved to the setup list above;
    keeping it here would have been redundant.

Verified:
- `npx tsc --noEmit` on `web/` clean
- Web image rebuilt and deployed

Confidence: high
Scope-risk: narrow — wizard text only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…UID checks

The wizard's Validate step previously only constructed the Teams adapter
(format check) — a typo'd App ID or wrong secret passed "validation" and
only failed later when channel enumeration silently returned []. Now:

- bridge.ts handleValidateAdapter actually mints a Graph token via MSAL
  and classifies AADSTS / unauthorized_client / invalid_client errors as
  credential failures; non-auth probe failures (403 consent, network)
  soft-accept with a pointer to Channel.ReadBasic.All admin consent.
- ConnectionWizard validates App ID / Tenant ID against the AAD GUID
  shape client-side, renders inline errors, and gates the Validate
  button until they pass.
- Teams is no longer treated as webhook-only: the Channels step renders
  the real Graph-enumerated channel list (depends on #206).

Verified live: a real Teams connection was created through this exact
flow today (channel discovery + message history sync working).

Constraint: validation must not require the messaging endpoint to be live yet
Rejected: server-side-only GUID validation | users deserve inline feedback before a round-trip
Confidence: high
Scope-risk: narrow
Not-tested: MultiTenant validation path against a real multi-org token

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… filename

The loose manifest.json referenced botId eefc03cb-… which does not exist
in any Azure tenant (stale id from an early registration attempt), and
was missing webApplicationInfo + RSC permissions — a package built from
it could install but never read channel history. The actual working
package (built via teams CLI) used the correct id but generic
"Developer/example.com" branding.

Merge the two: correct id (fb24e83f-…), manifest schema 1.25, RSC perms
(ChannelMessage.Read.Group, ChatMessage.Read.Chat), personal tabs, and
Beever AI branding. Bump to 1.0.3 (dev portal auto-bumped to the same).

build-package.mjs now writes beever-atlas-teams.zip (the name actually
used/uploaded everywhere) instead of beever-atlas-bot.zip; .gitignore
updated to match so the build artifact stays untracked.

Constraint: dev-portal catalog already at version 1.0.2 — local manifest must be ≥1.0.3
Rejected: tracking the built zip in git | reproducible artifact, build script exists for that
Confidence: high
Scope-risk: narrow
Directive: botId must equal the AAD app id fb24e83f-… — never regenerate it independently

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alan5543 alan5543 merged commit 98eaeaf into main Jun 1, 2026
9 checks passed
@alan5543 alan5543 deleted the fix/teams-setup-wizard-accuracy branch June 1, 2026 04:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant